// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import { AnyARecord } from 'dns';
import { stringify } from 'querystring';
import * as vscode from 'vscode';

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

	// Use the console to output diagnostic information (console.log) and errors (console.error)
	// This line of code will only be executed once when your extension is activated
	console.log('Congratulations, your extension "qbs" is now active!');

	var count = 0;

	const path=require("path");

    const get_filename = (path_filename:string): string => {

		const name = path.basename(path_filename);
		return name;
	};

    const get_fileext = (path_filename:String): string => {

		const ext = path.extname(path_filename);
		return ext;
	};


	const get_filename_without_ext = (path_filename:string): string => {

		const name = path.basename(path_filename);
		const ext = path.extname(path_filename);
		const name_without_ext = path.basename(name,ext);
		return name_without_ext;
	};

	const nnet = require("net");

	var host_address:string = "127.0.0.1";
	var host_port:string =    "27193";

	var host_port_int:number;
	host_port_int = Number(host_port);
	
	
	var conn_ok = 0;
    var client = nnet.createConnection({host:host_address, port: host_port_int}, () => {
		console.log("connected to server==========");
		conn_ok = 1;
	} );

	var stop = new Date().getTime();
	while (new Date().getTime() < stop + 3000) {
		if (conn_ok === 1){ break;}
	}

// Define a sleep function that returns a promise
function sleep(ms:number) {
	return new Promise((resolve) => setTimeout(resolve, ms));
  }
  
  // Use the sleep function with async/await
  async function main() {
	console.log("Before sleep");
	await sleep(1000); // Wait for one second
	console.log("After sleep");
  }
  

  
	var cur_activeTextEditor:any;
	//vscode.window.showInformationMessage('cannot connect action done!'); 

	if (conn_ok === 0){
		//vscode.window.showInformationMessage('init : try connect to host, have not got result! '); 
	}else{

		client.on('data', function(data:any){
			cur_activeTextEditor = vscode.window.activeTextEditor;
			const cur_pos = cur_activeTextEditor.selection.active;
			console.log( cur_pos	);
			
			cur_activeTextEditor.edit((edit:any) =>{
				edit.insert( cur_pos, data.toString() );
			}	 ); 
		} );
		conn_ok = 2;
		client.on('end', function(){ 
			conn_ok = 0;
		});
	}

    var myproc:any;

	var part_1:string = "<cmd-end/>\n\
<cmd-start/>\n\
\n\
<set-target-canvas>\n\
<canvas-filename>CURRENT-CANVAS</canvas-filename>\n\
</set-target-canvas>\n\
<网络文件独占模式>\n\
 <action--drop-package \n\
		       parent-uid = \"FIRST-CHOOSED\" \n\
                       x=\"500\" y =\"400\"  \n\
		       XY-确定方法 = \"FIRST-CHOOSED > RIGHT-TOP > 0 > 0\"\n\
                       flags = \"x-y-is-canvas-coordinate\"\n\
                       filename=\"./package/000/pkg/src-location.better.pkg\" start-pos=\"48\" \n\
                       />\n\
<sequence-operation-on-package>\n\
     <package-uid>CREATED-JUST-NOW</package-uid> \n\
\n\
<port-index> 4  </port-index>   <port-value>"

	var part_2:string = "</port-value> <port-index> 5  </port-index>   <port-value>";
	var part_3:string = "</port-value>";
	var part_4:string = "<package-uid>FIRST-CHOOSED</package-uid>\n\
	<get-package-or-jci-include-self/>\n\
	<发送canvas定位xml命令>\n\
		  <文件类型>";
	var part_5:string = "</文件类型>";
	var part_6:string = "</发送canvas定位xml命令>\n\
	</sequence-operation-on-package >\n\
	</网络文件独占模式>\n\
	<cmd-end/>   ";

	var part_a:string = "[";
	var part_b:string = "]";

	var relative_path_1 :string = "/home/guest/qbs/";
	var relative_path_2 :string = "~/qbs/";
		
	var QBS_INSTALL_PATH_1_not_set = 0;
	var QBS_INSTALL_PATH_2_not_set = 0;
	if ( process.env.QBS_INSTALL_PATH_1 ){
		relative_path_1 = process.env.QBS_INSTALL_PATH_1;
	}else{
		QBS_INSTALL_PATH_1_not_set = 1;	
	}
	if ( process.env.QBS_INSTALL_PATH_2 ){
		relative_path_2 = process.env.QBS_INSTALL_PATH_2;
	}else{
		QBS_INSTALL_PATH_2_not_set = 1;	
	}
	
	if (QBS_INSTALL_PATH_1_not_set ||  QBS_INSTALL_PATH_2_not_set ){
		vscode.window.showInformationMessage('ERROR: must set env var => QBS_INSTALL_PATH_1 and QBS_INSTALL_PATH_2!\n something like:export QBS_INSTALL_PATH_1=\"/home/{user}/qbs/\" \n  QBS_INSTALL_PATH_2=\"~/qbs/\"');  //this is ok
	}

	console.log( "QBS_INSTALL_PATH_1 is %s" ,relative_path_1  );
	console.log( "QBS_INSTALL_PATH_2 is %s" ,relative_path_2  );

	var relative_path_1_len:number = 0;
	var relative_path_2_len:number = 0;

	relative_path_1_len = relative_path_1.length;
	relative_path_2_len = relative_path_2.length;

	enum qbs_file_type {
		FILE_TYPE__UNKNOWN=  0,
		FILE_TYPE__C_SERIES ,
		FILE_TYPE__SHELL,
		FILE_TYPE__ELISP ,
		FILE_TYPE__PYTHON ,
	}

	var get_file_type = function ( filename:String){
		var ret:number = qbs_file_type.FILE_TYPE__UNKNOWN;
		var ext = get_fileext(filename);
        switch (ext){
			case "cpp": case "c" : case "h" : case "hpp" : case "c++": case "cc": case "hh":
				ret = qbs_file_type.FILE_TYPE__C_SERIES;
				break;
			case "py": case "vim":
				ret = qbs_file_type.FILE_TYPE__PYTHON;
				break;	
			case "el":
				ret = qbs_file_type.FILE_TYPE__ELISP;
				break;	
			case "sh":
				ret = qbs_file_type.FILE_TYPE__ELISP;
				break;					
			default:
			break;
		};
		return ret;
	};

	var set_const_string_according_file_type = function ( filetype:number){
		switch (filetype){
			case qbs_file_type.FILE_TYPE__UNKNOWN:
				part_a = "[";
				part_b = "]";
				break;
			case qbs_file_type.FILE_TYPE__C_SERIES:
				part_a = "//[";
				part_b = "]";
				break;
			case qbs_file_type.FILE_TYPE__SHELL:
				part_a = "#[";
				part_b = "]";
				break;
			
			case qbs_file_type.FILE_TYPE__ELISP:
				part_a = ";[";
				part_b = "]";
				break;
				
			case qbs_file_type.FILE_TYPE__PYTHON:
				part_a = "#[";
				part_b = "]";
				break;

			default:
				part_a = "[";
				part_b = "]";
				break;
		}



	};


const get_relative_filanme = (filename:string):string => {
	var ret:string;
	if (filename.startsWith(relative_path_1)){
		ret = filename.substring(relative_path_1_len);

		console.log("1 len: %d",  relative_path_1_len);
	}else if (filename.startsWith(relative_path_2)){
		ret = filename.substring(relative_path_2_len);
		console.log("2 len: %d",  relative_path_2_len);
	}else{
		ret = "";
	}
	if (ret.length > 0){
		if (ret[0] !== '/'){
			ret = "./" + ret;
		}else{
			ret = "." + ret;
		}
	}else{
		ret = "";
	}	
    return ret;
};
// Create a function for reusable perpose
const generateRandomString = (myLength:number) => {
	const chars =
	  "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890-_";
	const randomArray = Array.from(
	  { length: myLength },
	  (v, k) => chars[Math.floor(Math.random() * chars.length)]
	);
  
	const randomString = randomArray.join("");
	return randomString;
  };


const send_string_to_host = (data:string) => {
	var need_re_connect:number = 0;
	var need_set_callback:number = 0;

	if (conn_ok === 0 ){
		need_re_connect = 1;
	}else{
		if (client.readyState === "open" ){

		}else{
			need_re_connect = 1;
		}
	}
	if (need_re_connect === 0 ){
		if (conn_ok === 1 ){
			need_set_callback = 1;
		}
	}

	if (need_re_connect === 1 ){
		conn_ok = 0;
		need_set_callback = 1;
		client = nnet.createConnection({host:host_address, port: host_port_int}, () => {
			console.log("in hot key: connected to server");
			conn_ok = 1;
		} );
		var stop = new Date().getTime();
		while (new Date().getTime() < stop + 3000) {
			if (conn_ok === 1){ break;}
		}

	}

	if (need_set_callback === 1){
		if (conn_ok === 1){
			client.on('data', function(data:any){
				cur_activeTextEditor = vscode.window.activeTextEditor;
				const cur_pos = cur_activeTextEditor.selection.active;
				console.log( cur_pos	);
				
				cur_activeTextEditor.edit((edit:any) =>{
					edit.insert( cur_pos, data.toString() );
				}	 ); 
			} );
			conn_ok = 2;
			client.on('end', function(){ 
				conn_ok = 0;
			});
		}

	}


	


	if (conn_ok !== 2 ){
		vscode.window.showInformationMessage('connect to host is not ready!'); 
	}else{

		client.write(data);

	}



};

	// The command has been defined in the package.json file
	// Now provide the implementation of the command with registerCommand
	// The commandId parameter must match the command field in package.json
	let disposable = vscode.commands.registerCommand('qbs.helloWorld', () => {
		// The code you place here will be executed every time your command is executed
		// Display a message box to the user
		//vscode.window.showInformationMessage('Hello World from qbs!');  //this is ok

		const activeTextEditor = vscode.window.activeTextEditor;
		if (!activeTextEditor) {return;}
  
		const activeDocument = activeTextEditor.document;
		const selections = activeTextEditor.selections;
		//if (!selections.length || !activeDocument) { return; }
  
		const filename=activeDocument.fileName;
		//console.log()
		console.log('filename is %s', filename);

		count ++;
		console.log('count is %d', count);

		const ext = get_fileext(filename);
		console.log('file ext is %s', ext);


		set_const_string_according_file_type(get_file_type( filename) );
		var rs:string = generateRandomString(20);
		console.log('random string is %s', rs);
		var new_line:any;
		//if (activeTextEditor.selection.isEmpty){
			const cur_pos = activeTextEditor.selection.active;
			console.log( cur_pos	);
		//}
		new_line = cur_pos.line + 1;

		var relative_fn:string = get_relative_filanme(filename);
		console.log("%s  ==>  %s",filename , relative_fn);
		if (relative_fn !== ""){

			var output_to_buffer =  part_a + rs + part_b + "(%% " + " %%)\n";
			var target_col:number = output_to_buffer.length - 4;
			activeTextEditor.edit((edit) =>{
				edit.insert( new vscode.Position(new_line,0), output_to_buffer);
			}	 ); 
			var new_pos = new vscode.Position(new_line , target_col);
			var new_sel = new vscode.Selection(new_pos,new_pos);
			activeTextEditor.selection = new_sel;

		    var need_re_connect:number = 0;
			var need_set_callback:number = 0;

			if (conn_ok === 0 ){
				need_re_connect = 1;
			}else{
				if (client.readyState === "open" ){

				}else{
					need_re_connect = 1;
				}
			}
			if (need_re_connect === 0 ){
				if (conn_ok === 1 ){
					need_set_callback = 1;
				}
			}

			if (need_re_connect === 1 ){
				conn_ok = 0;
				need_set_callback = 1;
				client = nnet.createConnection({host:host_address, port: host_port_int}, () => {
					console.log("in hot key: connected to server");
					conn_ok = 1;
				} );
				var stop = new Date().getTime();
				while (new Date().getTime() < stop + 3000) {
					if (conn_ok === 1){ break;}
				}

			}

			if (need_set_callback === 1){
				if (conn_ok === 1){
					client.on('data', function(data:any){
						cur_activeTextEditor = vscode.window.activeTextEditor;
						const cur_pos = cur_activeTextEditor.selection.active;
						console.log( cur_pos	);
						
						cur_activeTextEditor.edit((edit:any) =>{
							edit.insert( cur_pos, data.toString() );
						}	 ); 
					} );
					conn_ok = 2;
					client.on('end', function(){ 
						conn_ok = 0;
					});
				}

			}


			


			if (conn_ok !== 2 ){
				vscode.window.showInformationMessage('connect to host is not ready!'); 
			}else{
				var str_to_host = part_1 + rs + part_2 + relative_fn + part_3 + part_4 + "c or cpp" + part_5 + part_6;
				client.write(str_to_host);
				console.log( relative_fn);
			}


		}else{
			// the file is not under qbs install directory, do nothing
		}



	});

	context.subscriptions.push(disposable);


	let disposable1 = vscode.commands.registerCommand('qbs.jumpUP', () => {
		// The code you place here will be executed every time your command is executed
		// Display a message box to the user
		//vscode.window.showInformationMessage('jumpUP from qbs!');  //this is ok

		var send_cmd_already = 0;

		const activeTextEditor = vscode.window.activeTextEditor;
		if (!activeTextEditor) {return;}
  
		const activeDocument = activeTextEditor.document;

		var new_line:any;
		//if (activeTextEditor.selection.isEmpty){
			const cur_pos = activeTextEditor.selection.active;
			console.log( cur_pos	);
		//}
		new_line = cur_pos.line + 1;

		var start__line = ((cur_pos.line - 50 ) < 0) ? 0:  (cur_pos.line - 50 );
		var search__start_pos = new vscode.Position ( start__line, 0);

		const search__text = activeDocument.getText( new vscode.Range(search__start_pos , cur_pos));
		var start__index =  search__text.lastIndexOf("(%%");
		var start__col = 0;
		console.log( start__index);
		if (start__index >= 0){
			//ok, found "(%%"  
			for ( var tt1 = 0; tt1 < search__text.length; tt1 ++ ){
				if ( search__text[tt1] === "\r"){
				}
				if ( search__text[tt1] === "\n"){
					start__line ++;
					start__col = 0;

				}else{
					if ( search__text[tt1] === "\r"){
					}else{
						start__col ++;
					}
				}
				if ( tt1 >= start__index){
					start__col --;
					break;
				}

			}

			console.log( "start pos : %d %d", start__line, start__col );

			var end__line =  start__line + 20; 
			var search_1__start_pos = new vscode.Position ( start__line, start__col);

			const search_1__text = activeDocument.getText( new vscode.Range(search_1__start_pos , new vscode.Position( end__line, 0) ));
			var end__index =  search_1__text.lastIndexOf("%%)");
			var end__col = 0;

			if (  end__index >= 0){

				var new_pos = new vscode.Position(start__line , start__col);
				var new_sel = new vscode.Selection(new_pos,new_pos);
				activeTextEditor.selection = new_sel;

				activeTextEditor.revealRange(new vscode.Range( new_pos , new_pos) ); 


				var output_string_to_host = search_1__text.substring(0, end__index + "%%)".length);
				console.log( "output sring is:%s", output_string_to_host);
				send_string_to_host(output_string_to_host );
				send_cmd_already = 1;

			}else{
				// not found "%%)" 
			}

		}else{
			// not found "(%%" 
		}


		
		if (send_cmd_already){

		}else{
			vscode.window.showInformationMessage('jumpUP: target string not found!');  //this is ok
		}

		



	});

	context.subscriptions.push(disposable1);

	let disposable4 = vscode.commands.registerCommand('qbs.jumpDOWN', () => {
		// The code you place here will be executed every time your command is executed
		// Display a message box to the user
		//vscode.window.showInformationMessage('jumpDOWN from qbs!');  //this is ok

		var send_cmd_already = 0;

		const activeTextEditor = vscode.window.activeTextEditor;
		if (!activeTextEditor) {return;}
  
		const activeDocument = activeTextEditor.document;

		var new_line:any;
		//if (activeTextEditor.selection.isEmpty){
			const cur_pos = activeTextEditor.selection.active;
			console.log( cur_pos	);
		//}
		new_line = cur_pos.line + 1;

		var end__line = cur_pos.line + 50 ;
		var search__end_pos = new vscode.Position ( end__line, 0);

		const search__text = activeDocument.getText( new vscode.Range( cur_pos, search__end_pos ));
		var end__index =  search__text.indexOf("%%)");
		var end__col = 0;

		end__line = cur_pos.line;
		console.log( end__index);
		if (end__index >= 0){
			//ok, found "(%%"  
			for ( var tt1 = 0; tt1 < search__text.length; tt1 ++ ){
				if ( search__text[tt1] === "\r"){
				}
				if ( search__text[tt1] === "\n"){
					end__line ++;
					end__col = 0;

				}else{
					if ( search__text[tt1] === "\r"){
					}else{
						end__col ++;
					}
				}
				if ( tt1 >= end__index){
					end__col --;
					break;
				}

			}

			end__col = end__col + 3;

			console.log( "end pos : %d %d", end__line, end__col );

			var start__line =  (end__line - 20 < 0) ? 0 : end__line - 20 ; 
			var search_1__start_pos = new vscode.Position ( start__line, 0);

			const search_1__text = activeDocument.getText( new vscode.Range(search_1__start_pos , new vscode.Position( end__line, end__col) ));
			var start__index =  search_1__text.lastIndexOf("(%%");
			

			if (  start__index >= 0){

				var new_pos = new vscode.Position(end__line , end__col);
				var new_sel = new vscode.Selection(new_pos,new_pos);
				activeTextEditor.selection = new_sel;

				activeTextEditor.revealRange(new vscode.Range( new_pos , new_pos) ); 

				var output_string_to_host = search_1__text.substring( start__index );
				console.log( "output sring is:%s", output_string_to_host);
				send_string_to_host(output_string_to_host );
				send_cmd_already = 1;

			}else{
				// not found "%%)" 
			}

		}else{
			// not found "(%%" 
		}


		if (send_cmd_already){

		}else{
			vscode.window.showInformationMessage('jumpDOWN: target string not found!');  //this is ok
		}

		





	});

	context.subscriptions.push(disposable4);



}

// This method is called when your extension is deactivated
export function deactivate() {} 
